package com.bigfans.userservice.api;

import com.bigfans.Constants;
import com.bigfans.framework.CurrentUser;
import com.bigfans.framework.SessionUserFactory;
import com.bigfans.framework.exception.UserExistsException;
import com.bigfans.framework.exception.UserUnAuthorizedException;
import com.bigfans.framework.kafka.KafkaTemplate;
import com.bigfans.framework.utils.JsonUtils;
import com.bigfans.framework.utils.JwtUtils;
import com.bigfans.framework.utils.StringHelper;
import com.bigfans.framework.web.*;
import com.bigfans.model.event.notification.RequestVCodeEvent;
import com.bigfans.userservice.model.User;
import com.bigfans.userservice.service.UserService;
import com.bigfans.userservice.service.impl.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
public class UserApi extends BaseController{

    @Autowired
    private RedisService redisService;
    @Autowired
    private UserService userService;
    @Autowired
    private KafkaTemplate kafkaTemplate;

    @GetMapping("/currentUser")
	public RestResponse getByToken(String userToken){
        CurrentUser currentUser = redisService.getSessionUser(userToken);
        if(currentUser == null){
            currentUser = new CurrentUser();
            currentUser.setUid("2");
        }
        return RestResponse.ok(currentUser);
    }

    /**
     * 执行登录请求
     *
     * @param user
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public RestResponse login(@RequestBody User user) throws Exception {
        User loginUser = userService.login(user.getAccount(), user.getPassword());
        if (loginUser == null) {
            throw new UserUnAuthorizedException();
        }
        this.createSessionUser(loginUser);
        return RestResponse.ok();
    }

    @RequestMapping(value = "/validateMobile", method = RequestMethod.POST)
    public RestResponse validateMobile(@RequestParam(name = "mobile") String mobile) throws Exception {
        boolean accountExist = userService.accountExist(mobile);
        return RestResponse.ok(accountExist);
    }

    @RequestMapping(value = "/requestVCode", method = RequestMethod.POST)
    public RestResponse sendVerificationCode(@RequestParam(name = "mobile") String mobile) {
        assert StringHelper.isNotEmpty(mobile);
        String code = StringHelper.createNumCode(6);
        kafkaTemplate.send(new RequestVCodeEvent(mobile , code));
        redisService.setVerificationCode(mobile , code);
        return RestResponse.ok();
    }

    /**
     * 执行退出请求
     *
     * @return RestResponse
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public RestResponse logout() {
        getRequest().getSession().invalidate();
        Cookie userCookie = CookieHolder.get(Constants.TOKEN.KEY_NAME);
        if(userCookie != null){
            userCookie.setMaxAge(0);
            userCookie.setPath("/");
        }
        return RestResponse.ok();
    }

    /**
     * 执行注册请求
     *
     * @param userExample
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public RestResponse register(User userExample) throws Exception {
        String verificationCode = redisService.getVerificationCode(userExample.getMobile());
        // 检测验证码
        if (!userExample.getVerificationCode().equals(verificationCode)) {
            return RestResponse.error(ResponseStatus.CODE_INCORRECT, "");
        }
        // 判断用户是否存在
        if (userService.exist(userExample)) {
            throw new UserExistsException();
        }
        userExample.setMobile(userExample.getAccount());
        User user = userService.regist(userExample);
        this.createSessionUser(user);
        return RestResponse.ok();
    }

    private void createSessionUser(User user){
        Map<String , Object> claims = new HashMap<>();
        claims.put("account" , user.getAccount());
        claims.put("nickname" , user.getNickname());
        claims.put("ip" , RequestHolder.getRemoteIP());
        claims.put("loginTime" , new Date());
        claims.put("uid" , user.getId());
        claims.put("loggedIn" , true);
        CurrentUser currentUser = SessionUserFactory.createSessionUser(claims);
        this.saveToken(JsonUtils.toJsonString(currentUser));
    }

    private void saveToken(String tokenStr){
        String jwtTokenStr = JwtUtils.create(tokenStr, "bigfans");
        // 登录后更新cookie中的userkey
        // 如果选择了记住我,将用户信息存入redis中
        Cookie cookie = new Cookie(Constants.TOKEN.KEY_NAME, jwtTokenStr);
        // 如果不设置路径,只有当前路径和自路径可以访问,访问其他地址时候cookie不会被传递到服务端
        cookie.setPath("/");
        cookie.setDomain("localhost");
        // 设置7天内有效
        cookie.setMaxAge(60 * 60 * 24 * 7);
        // 浏览器退出时清空cookie
        // cookie.setMaxAge(-1);
        HttpServletResponse httpServletResponse = ResponseHolder.getHttpServletResponse();
        httpServletResponse.addCookie(cookie);
    }
}
